using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Runtime.CompilerServices;
using PickGold.Charting;
using PickGold.Charting.Utilities;

namespace PickGold.Charting.ChartTypes
{
	internal class PointChart : IChartType, IDisposable
	{
		internal bool alwaysDrawMarkers;
		internal bool autoLabelPosition;
		internal bool indexedSeries;
		internal ArrayList label3DInfoList;
		internal LabelAlignmentStyles labelPosition;
		internal int labelYValueIndex;
		internal bool middleMarker;

		public PointChart()
		{
			this.alwaysDrawMarkers = true;
			this.labelYValueIndex = -1;
			this.autoLabelPosition = true;
			this.labelPosition = LabelAlignmentStyles.Top;
			this.middleMarker = true;
		}

		public PointChart(bool alwaysDrawMarkers)
		{
			this.alwaysDrawMarkers = true;
			this.labelYValueIndex = -1;
			this.autoLabelPosition = true;
			this.labelPosition = LabelAlignmentStyles.Top;
			this.middleMarker = true;
			this.alwaysDrawMarkers = alwaysDrawMarkers;
		}

		public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list)
		{
			this.Common = common;
			this.indexedSeries = ChartHelper.IndexedSeries(this.Common, area.GetSeriesFromChartType(this.Name).ToArray());
			Axis axis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName);
			Axis axis2 = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName);
			int num = 0;
			int num2 = 1;
			foreach (DataPoint point in series.Points)
			{
				double yValue = this.GetYValue(common, area, series, point, num2 - 1, this.YValueIndex);
				yValue = axis2.GetLogValue(yValue);
				if ((yValue > axis2.ViewMaximum) || (yValue < axis2.ViewMinimum))
				{
					num2++;
					continue;
				}
				double logValue = this.indexedSeries ? ((double)num2) : point.XValue;
				logValue = axis.GetLogValue(logValue);
				if ((logValue > axis.ViewMaximum) || (logValue < axis.ViewMinimum))
				{
					num2++;
					continue;
				}
				if (!this.ShouldDrawMarkerOnViewEdgeX())
				{
					if ((logValue == axis.ViewMaximum) && (this.ShiftedX >= 0.0))
					{
						num2++;
						continue;
					}
					if ((logValue == axis.ViewMinimum) && (this.ShiftedX <= 0.0))
					{
						num2++;
						continue;
					}
				}
				PointF empty = PointF.Empty;
				empty.Y = (float)axis2.GetLinearPosition(yValue);
				if (this.indexedSeries)
				{
					empty.X = (float)axis.GetPosition((double)num2);
				}
				else
				{
					empty.X = (float)axis.GetPosition(point.XValue);
				}
				empty.X += (float)this.ShiftedX;
				int markerSize = point.MarkerSize;
				string markerImage = point.MarkerImage;
				MarkerStyle markerStyle = point.MarkerStyle;
				SizeF size = this.GetMarkerSize(common.graph, common, area, point, markerSize, markerImage);
				if (area.Area3DStyle.Enable3D)
				{
					float num6;
					float num7;
					area.GetSeriesZPositionAndDepth(series, out num6, out num7);
					Point3D[] points = new Point3D[] { new Point3D(empty.X, empty.Y, num7 + (this.middleMarker ? (num6 / 2f) : num6)) };
					area.matrix3D.TransformPoints(points);
					empty = points[0].PointF;
				}
				if ((this.alwaysDrawMarkers || (markerStyle != MarkerStyle.None)) || (markerImage.Length > 0))
				{
					if (num == 0)
					{
						size = common.graph.GetRelativeSize(size);
						RectangleF ef2 = new RectangleF(empty.X - (size.Width / 2f), empty.Y - (size.Height / 2f), size.Width, size.Height);
						list.Add(ef2);
					}
					num++;
					if (series.MarkerStep == num)
					{
						num = 0;
					}
				}
				num2++;
			}
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
		}

		internal void DrawAccumulated3DLabels(ChartGraphics graph, CommonElements common, ChartArea area)
		{
			if (this.label3DInfoList != null)
			{
				foreach (Label3DInfo info in this.label3DInfoList)
				{
					this.DrawLabels(area, graph, common, info.MarkerPosition, (int)info.MarkerSize.Height, info.PointEx.dataPoint, info.PointEx.dataPoint.series, info.PointEx.index - 1);
				}
				this.label3DInfoList.Clear();
			}
		}

		private void DrawLabels(ChartArea area, ChartGraphics graph, CommonElements common, PointF markerPosition, int markerSize, DataPoint point, Series ser, int pointIndex)
		{
			string label = point.Label;
			bool isValueShownAsLabel = point.IsValueShownAsLabel;
			if ((!point.IsEmpty && ((ser.IsValueShownAsLabel || isValueShownAsLabel) || (label.Length > 0))) || (isValueShownAsLabel || (label.Length > 0)))
			{
				using (StringFormat format = new StringFormat())
				{
					string str2;
					int num2;
					format.Alignment = StringAlignment.Near;
					format.LineAlignment = StringAlignment.Center;
					if (label.Length == 0)
					{
						str2 = ValueConverter.FormatValue(ser.Chart, point, point.Tag, point.YValues[(this.labelYValueIndex == -1) ? this.YValueIndex : this.labelYValueIndex], point.LabelFormat, ser.YValueType, ChartElementType.DataPoint);
					}
					else
					{
						str2 = point.ReplaceKeywords(label);
					}
					SizeF relativeSize = graph.GetRelativeSize(new SizeF((float)markerSize, (float)markerSize));
					SizeF labelSize = graph.GetRelativeSize(graph.MeasureString(str2, point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic));
					SizeF ef3 = graph.GetRelativeSize(graph.MeasureString("W", point.Font, new SizeF(1000f, 1000f), StringFormat.GenericTypographic));
					SizeF size = new SizeF(labelSize.Width, labelSize.Height);
					float num = size.Width / ((float)str2.Length);
					size.Height += ef3.Height / 2f;
					size.Width += num;
					string strA = point["LabelStyle"];
					if ((strA == null) || (strA.Length == 0))
					{
						strA = ser["LabelStyle"];
					}
					this.autoLabelPosition = true;
					if ((strA != null) && (strA.Length > 0))
					{
						this.autoLabelPosition = false;
						if (string.Compare(strA, "Auto", StringComparison.OrdinalIgnoreCase) != 0)
						{
							if (string.Compare(strA, "Center", StringComparison.OrdinalIgnoreCase) != 0)
							{
								if (string.Compare(strA, "Bottom", StringComparison.OrdinalIgnoreCase) != 0)
								{
									if (string.Compare(strA, "TopLeft", StringComparison.OrdinalIgnoreCase) != 0)
									{
										if (string.Compare(strA, "TopRight", StringComparison.OrdinalIgnoreCase) != 0)
										{
											if (string.Compare(strA, "BottomLeft", StringComparison.OrdinalIgnoreCase) != 0)
											{
												if (string.Compare(strA, "BottomRight", StringComparison.OrdinalIgnoreCase) != 0)
												{
													if (string.Compare(strA, "Left", StringComparison.OrdinalIgnoreCase) != 0)
													{
														if (string.Compare(strA, "Right", StringComparison.OrdinalIgnoreCase) != 0)
														{
															if (string.Compare(strA, "Top", StringComparison.OrdinalIgnoreCase) != 0)
															{
																throw new ArgumentException(SR.ExceptionCustomAttributeValueInvalid(strA, "LabelStyle"));
															}
															this.labelPosition = LabelAlignmentStyles.Top;
														}
														else
														{
															this.labelPosition = LabelAlignmentStyles.Right;
														}
													}
													else
													{
														this.labelPosition = LabelAlignmentStyles.Left;
													}
												}
												else
												{
													this.labelPosition = LabelAlignmentStyles.BottomRight;
												}
											}
											else
											{
												this.labelPosition = LabelAlignmentStyles.BottomLeft;
											}
										}
										else
										{
											this.labelPosition = LabelAlignmentStyles.TopRight;
										}
									}
									else
									{
										this.labelPosition = LabelAlignmentStyles.TopLeft;
									}
								}
								else
								{
									this.labelPosition = LabelAlignmentStyles.Bottom;
								}
							}
							else
							{
								this.labelPosition = LabelAlignmentStyles.Center;
							}
						}
						else
						{
							this.autoLabelPosition = true;
						}
					}
					if (this.autoLabelPosition)
					{
						this.labelPosition = this.GetAutoLabelPosition(ser, pointIndex);
					}
					PointF labelPosition = new PointF(markerPosition.X, markerPosition.Y);
					switch (this.labelPosition)
					{
						case LabelAlignmentStyles.Top:
							format.Alignment = StringAlignment.Center;
							labelPosition.Y -= relativeSize.Height / 1.75f;
							labelPosition.Y -= size.Height / 2f;
							goto Label_05D6;

						case LabelAlignmentStyles.Bottom:
							format.Alignment = StringAlignment.Center;
							labelPosition.Y += relativeSize.Height / 1.75f;
							labelPosition.Y += size.Height / 2f;
							goto Label_05D6;

						case (LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Top):
							goto Label_05D6;

						case LabelAlignmentStyles.Right:
							labelPosition.X += (relativeSize.Height / 1.75f) + (num / 2f);
							goto Label_05D6;

						case LabelAlignmentStyles.Left:
							format.Alignment = StringAlignment.Far;
							labelPosition.X -= (relativeSize.Height / 1.75f) + (num / 2f);
							goto Label_05D6;

						case LabelAlignmentStyles.TopLeft:
							format.Alignment = StringAlignment.Far;
							labelPosition.X -= (relativeSize.Height / 1.75f) + (num / 2f);
							labelPosition.Y -= relativeSize.Height / 1.75f;
							labelPosition.Y -= size.Height / 2f;
							goto Label_05D6;

						case LabelAlignmentStyles.BottomRight:
							labelPosition.X += (relativeSize.Height / 1.75f) + (num / 2f);
							labelPosition.Y += relativeSize.Height / 1.75f;
							labelPosition.Y += size.Height / 2f;
							goto Label_05D6;

						case LabelAlignmentStyles.Center:
							format.Alignment = StringAlignment.Center;
							break;

						case LabelAlignmentStyles.TopRight:
							labelPosition.X += (relativeSize.Height / 1.75f) + (num / 2f);
							labelPosition.Y -= relativeSize.Height / 1.75f;
							labelPosition.Y -= size.Height / 2f;
							goto Label_05D6;

						case LabelAlignmentStyles.BottomLeft:
							format.Alignment = StringAlignment.Far;
							labelPosition.X -= (relativeSize.Height / 1.75f) + (num / 2f);
							labelPosition.Y += relativeSize.Height / 1.75f;
							labelPosition.Y += size.Height / 2f;
							goto Label_05D6;
					}
				Label_05D6:
					num2 = point.LabelAngle;
					if (str2.Trim().Length == 0)
					{
						return;
					}
					if (ser.SmartLabelStyle.Enabled)
					{
						labelPosition = area.smartLabels.AdjustSmartLabelPosition(common, graph, area, ser.SmartLabelStyle, labelPosition, labelSize, format, markerPosition, relativeSize, this.labelPosition);
						num2 = 0;
					}
					if ((num2 == 90) || (num2 == -90))
					{
						LabelAlignmentStyles styles2 = this.labelPosition;
						if (styles2 <= LabelAlignmentStyles.TopLeft)
						{
							switch (styles2)
							{
								case LabelAlignmentStyles.Top:
									format.Alignment = StringAlignment.Near;
									labelPosition.Y += size.Height / 2f;
									goto Label_0707;

								case LabelAlignmentStyles.Bottom:
									format.Alignment = StringAlignment.Far;
									labelPosition.Y -= size.Height / 2f;
									goto Label_0707;

								case (LabelAlignmentStyles.Bottom | LabelAlignmentStyles.Top):
									goto Label_0707;

								case LabelAlignmentStyles.Right:
									format.Alignment = StringAlignment.Center;
									format.LineAlignment = StringAlignment.Near;
									goto Label_0707;

								case LabelAlignmentStyles.Left:
									goto Label_06E7;

								case LabelAlignmentStyles.TopLeft:
									goto Label_06F7;
							}
						}
						else if (((styles2 != LabelAlignmentStyles.TopRight) && (styles2 != LabelAlignmentStyles.BottomLeft)) && (styles2 == LabelAlignmentStyles.BottomRight))
						{
							goto Label_0700;
						}
					}
					goto Label_0707;
				Label_06E7:
					format.Alignment = StringAlignment.Center;
					format.LineAlignment = StringAlignment.Center;
					goto Label_0707;
				Label_06F7:
					format.Alignment = StringAlignment.Near;
					goto Label_0707;
				Label_0700:
					format.Alignment = StringAlignment.Far;
				Label_0707:
					if (labelPosition.IsEmpty)
					{
						return;
					}
					RectangleF empty = RectangleF.Empty;
					size.Height -= labelSize.Height / 2f;
					size.Height += labelSize.Height / 8f;
					empty = GetLabelPosition(graph, labelPosition, size, format, true);
					switch (this.labelPosition)
					{
						case LabelAlignmentStyles.Right:
							empty.X -= num / 2f;
							break;

						case LabelAlignmentStyles.Left:
							empty.X += num / 2f;
							break;

						case LabelAlignmentStyles.TopLeft:
							empty.X += num / 2f;
							break;

						case LabelAlignmentStyles.TopRight:
							empty.X -= num / 2f;
							break;

						case LabelAlignmentStyles.BottomLeft:
							empty.X += num / 2f;
							break;

						case LabelAlignmentStyles.BottomRight:
							empty.X -= num / 2f;
							break;
					}
					using (Brush brush = new SolidBrush(point.LabelForeColor))
					{
						graph.DrawPointLabelStringRel(common, str2, point.Font, brush, labelPosition, format, num2, empty, point.LabelBackColor, point.LabelBorderColor, point.LabelBorderWidth, point.LabelBorderDashStyle, ser, point, pointIndex);
					}
				}
			}
		}

		protected virtual void DrawPointMarker(ChartGraphics graph, Series series, DataPoint dataPoint, PointF point, MarkerStyle markerStyle, int markerSize, Color markerColor, Color markerBorderColor, int markerBorderSize, string markerImage, Color markerImageTransparentColor, int shadowSize, Color shadowColor, RectangleF imageScaleRect)
		{
			graph.DrawMarkerRel(point, markerStyle, markerSize, markerColor, markerBorderColor, markerBorderSize, markerImage, markerImageTransparentColor, shadowSize, shadowColor, imageScaleRect);
		}

		protected virtual LabelAlignmentStyles GetAutoLabelPosition(Series series, int pointIndex)
		{
			return LabelAlignmentStyles.Top;
		}

		internal double GetEmptyPointValue(DataPoint point, int pointIndex)
		{
			Series series = point.series;
			double d = 0.0;
			double naN = 0.0;
			int num3 = 0;
			int num4 = series.Points.Count - 1;
			string strA = "";
			if (series.EmptyPointStyle.IsCustomPropertySet("EmptyPointValue"))
			{
				strA = series.EmptyPointStyle["EmptyPointValue"];
			}
			else if (series.IsCustomPropertySet("EmptyPointValue"))
			{
				strA = series["EmptyPointValue"];
			}
			if (string.Compare(strA, "Zero", StringComparison.OrdinalIgnoreCase) == 0)
			{
				return 0.0;
			}
			for (int i = pointIndex; i >= 0; i--)
			{
				if (!series.Points[i].IsEmpty)
				{
					d = series.Points[i].YValues[this.YValueIndex];
					num3 = i;
					break;
				}
				d = double.NaN;
			}
			for (int j = pointIndex; j < series.Points.Count; j++)
			{
				if (!series.Points[j].IsEmpty)
				{
					naN = series.Points[j].YValues[this.YValueIndex];
					num4 = j;
					break;
				}
				naN = double.NaN;
			}
			if (double.IsNaN(d))
			{
				if (double.IsNaN(naN))
				{
					d = 0.0;
				}
				else
				{
					d = naN;
				}
			}
			if (double.IsNaN(naN))
			{
				naN = d;
			}
			if (series.Points[num4].XValue == series.Points[num3].XValue)
			{
				return ((d + naN) / 2.0);
			}
			double num7 = (d - naN) / (series.Points[num4].XValue - series.Points[num3].XValue);
			return ((-num7 * (point.XValue - series.Points[num3].XValue)) + d);
		}

		public virtual Image GetImage(ChartTypeRegistry registry)
		{
			return (Image)registry.ResourceManager.GetObject(this.Name + "ChartType");
		}

		internal static RectangleF GetLabelPosition(ChartGraphics graph, PointF position, SizeF size, StringFormat format, bool adjustForDrawing)
		{
			RectangleF empty = RectangleF.Empty;
			empty.Width = size.Width;
			empty.Height = size.Height;
			SizeF relativeSize = SizeF.Empty;
			if (graph != null)
			{
				relativeSize = graph.GetRelativeSize(new SizeF(1f, 1f));
			}
			if (format.Alignment == StringAlignment.Far)
			{
				empty.X = position.X - size.Width;
				if (adjustForDrawing && !relativeSize.IsEmpty)
				{
					empty.X -= 4f * relativeSize.Width;
					empty.Width += 4f * relativeSize.Width;
				}
			}
			else if (format.Alignment == StringAlignment.Near)
			{
				empty.X = position.X;
				if (adjustForDrawing && !relativeSize.IsEmpty)
				{
					empty.Width += 4f * relativeSize.Width;
				}
			}
			else if (format.Alignment == StringAlignment.Center)
			{
				empty.X = position.X - (size.Width / 2f);
				if (adjustForDrawing && !relativeSize.IsEmpty)
				{
					empty.X -= 2f * relativeSize.Width;
					empty.Width += 4f * relativeSize.Width;
				}
			}
			if (format.LineAlignment == StringAlignment.Far)
			{
				empty.Y = position.Y - size.Height;
			}
			else if (format.LineAlignment == StringAlignment.Near)
			{
				empty.Y = position.Y;
			}
			else if (format.LineAlignment == StringAlignment.Center)
			{
				empty.Y = position.Y - (size.Height / 2f);
			}
			empty.Y -= 1f * relativeSize.Height;
			return empty;
		}

		public virtual LegendImageStyle GetLegendImageStyle(Series series)
		{
			return LegendImageStyle.Marker;
		}

		protected virtual int GetMarkerBorderSize(DataPointCustomProperties point)
		{
			return point.MarkerBorderWidth;
		}

		protected virtual SizeF GetMarkerSize(ChartGraphics graph, CommonElements common, ChartArea area, DataPoint point, int markerSize, string markerImage)
		{
			SizeF size = new SizeF((float)markerSize, (float)markerSize);
			if ((graph != null) && (graph.Graphics != null))
			{
				size.Width = (markerSize * graph.Graphics.DpiX) / 96f;
				size.Height = (markerSize * graph.Graphics.DpiY) / 96f;
			}
			if (markerImage.Length > 0)
			{
				common.ImageLoader.GetAdjustedImageSize(markerImage, graph.Graphics, ref size);
			}
			return size;
		}

		public virtual double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex)
		{
			if (yValueIndex == -1)
			{
				return 0.0;
			}
			if (point.YValues.Length <= yValueIndex)
			{
				throw new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(this.Name, this.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)));
			}
			if (!point.IsEmpty && !double.IsNaN(point.YValues[yValueIndex]))
			{
				return point.YValues[yValueIndex];
			}
			double emptyPointValue = this.GetEmptyPointValue(point, pointIndex);
			if (emptyPointValue == 0.0)
			{
				Axis axis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName);
				double maximum = axis.maximum;
				double minimum = axis.minimum;
				if (emptyPointValue < minimum)
				{
					return minimum;
				}
				if (emptyPointValue > maximum)
				{
					emptyPointValue = maximum;
				}
			}
			return emptyPointValue;
		}

		public virtual void Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			this.Common = common;
			this.Area = area;
			this.ProcessChartType(false, graph, common, area, seriesToDraw);
		}

		protected virtual void ProcessChartType(bool selection, ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			this.Common = common;
			if (area.Area3DStyle.Enable3D)
			{
				this.ProcessChartType3D(selection, graph, common, area, seriesToDraw);
			}
			else
			{
				if (this.ShiftedSerName.Length == 0)
				{
					this.indexedSeries = ChartHelper.IndexedSeries(this.Common, area.GetSeriesFromChartType(this.Name).ToArray());
				}
				else
				{
					this.indexedSeries = ChartHelper.IndexedSeries(common.DataManager.Series[this.ShiftedSerName]);
				}
				foreach (Series series in common.DataManager.Series)
				{
					bool flag = false;
					if (this.ShiftedSerName.Length > 0)
					{
						if (this.ShiftedSerName != series.Name)
						{
							continue;
						}
						flag = true;
					}
					if ((((string.Compare(series.ChartTypeName, this.Name, true, CultureInfo.CurrentCulture) == 0) && (series.ChartArea == area.Name)) && series.IsVisible()) && ((seriesToDraw == null) || (seriesToDraw.Name == series.Name)))
					{
						this.HAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName);
						this.VAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName);
						double viewMaximum = this.HAxis.ViewMaximum;
						double viewMinimum = this.HAxis.ViewMinimum;
						double num3 = this.VAxis.ViewMaximum;
						double num4 = this.VAxis.ViewMinimum;
						if (!selection)
						{
							common.Chart.CallOnPrePaint(new ChartPaintEventArgs(series, graph, common, area.PlotAreaPosition));
						}
						int num5 = 0;
						int num6 = 1;
						foreach (DataPoint point in series.Points)
						{
							point.positionRel = new PointF(float.NaN, float.NaN);
							double yValue = this.indexedSeries ? ((double)num6) : point.XValue;
							yValue = this.HAxis.GetLogValue(yValue);
							if ((yValue > viewMaximum) || (yValue < viewMinimum))
							{
								num6++;
								continue;
							}
							double logValue = this.GetYValue(common, area, series, point, num6 - 1, this.YValueIndex);
							logValue = this.VAxis.GetLogValue(logValue);
							if ((logValue > num3) || (logValue < num4))
							{
								num6++;
								continue;
							}
							bool flag2 = false;
							if (!this.ShouldDrawMarkerOnViewEdgeX())
							{
								if ((yValue == viewMaximum) && (this.ShiftedX >= 0.0))
								{
									flag2 = true;
								}
								if ((yValue == viewMinimum) && (this.ShiftedX <= 0.0))
								{
									flag2 = true;
								}
							}
							int markerSize = point.MarkerSize;
							string markerImage = point.MarkerImage;
							MarkerStyle markerStyle = point.MarkerStyle;
							PointF empty = PointF.Empty;
							empty.Y = (float)this.VAxis.GetLinearPosition(logValue);
							if (this.indexedSeries)
							{
								empty.X = (float)this.HAxis.GetPosition((double)num6);
							}
							else
							{
								empty.X = (float)this.HAxis.GetPosition(point.XValue);
							}
							empty.X += (float)this.ShiftedX;
							point.positionRel = new PointF(empty.X, empty.Y);
							SizeF ef = this.GetMarkerSize(graph, common, area, point, markerSize, markerImage);
							if (flag2)
							{
								num6++;
								continue;
							}
							if ((this.alwaysDrawMarkers || (markerStyle != MarkerStyle.None)) || (markerImage.Length > 0))
							{
								if (common.ProcessModePaint)
								{
									if (num5 == 0)
									{
										graph.StartHotRegion(point);
										this.DrawPointMarker(graph, point.series, point, empty, (markerStyle == MarkerStyle.None) ? MarkerStyle.Circle : markerStyle, (int)ef.Height, (point.MarkerColor == Color.Empty) ? point.Color : point.MarkerColor, (point.MarkerBorderColor == Color.Empty) ? point.BorderColor : point.MarkerBorderColor, this.GetMarkerBorderSize(point), markerImage, point.MarkerImageTransparentColor, (point.series != null) ? point.series.ShadowOffset : 0, (point.series != null) ? point.series.ShadowColor : Color.Empty, new RectangleF(empty.X, empty.Y, ef.Width, ef.Height));
										graph.EndHotRegion();
									}
									if (common.ProcessModeRegions)
									{
										this.SetHotRegions(common, graph, point, ef, point.series.Name, num6 - 1, markerStyle, empty);
									}
								}
								num5++;
								if (series.MarkerStep == num5)
								{
									num5 = 0;
								}
							}
							graph.StartHotRegion(point, true);
							this.DrawLabels(area, graph, common, empty, (int)ef.Height, point, series, num6 - 1);
							graph.EndHotRegion();
							num6++;
						}
						if (!selection)
						{
							common.Chart.CallOnPostPaint(new ChartPaintEventArgs(series, graph, common, area.PlotAreaPosition));
						}
						if (flag)
						{
							break;
						}
					}
				}
			}
		}

		protected virtual void ProcessChartType3D(bool selection, ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
			List<string> seriesNamesList = null;
			if ((area.Area3DStyle.IsClustered && this.SideBySideSeries) || this.Stacked)
			{
				seriesNamesList = area.GetSeriesFromChartType(this.Name);
			}
			else
			{
				seriesNamesList = new List<string>();
				seriesNamesList.Add(seriesToDraw.Name);
			}
			foreach (object obj2 in area.GetDataPointDrawingOrder(seriesNamesList, this, selection, COPCoordinates.X, null, this.YValueIndex, false))
			{
				this.ProcessSinglePoint3D((DataPoint3D)obj2, graph, common, area);
			}
			this.DrawAccumulated3DLabels(graph, common, area);
		}

		internal void ProcessSinglePoint3D(DataPoint3D pointEx, ChartGraphics graph, CommonElements common, ChartArea area)
		{
			DataPoint dataPoint = pointEx.dataPoint;
			Series series = dataPoint.series;
			dataPoint.positionRel = new PointF(float.NaN, float.NaN);
			this.HAxis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName);
			this.VAxis = area.GetAxis(AxisName.Y, series.YAxisType, series.YSubAxisName);
			double yValue = this.GetYValue(common, area, series, pointEx.dataPoint, pointEx.index - 1, this.YValueIndex);
			yValue = this.VAxis.GetLogValue(yValue);
			if ((yValue > this.VAxis.ViewMaximum) || (yValue < this.VAxis.ViewMinimum))
			{
				return;
			}
			double logValue = pointEx.indexedSeries ? ((double)pointEx.index) : dataPoint.XValue;
			logValue = this.HAxis.GetLogValue(logValue);
			if ((logValue > this.HAxis.ViewMaximum) || (logValue < this.HAxis.ViewMinimum))
			{
				return;
			}
			if (!this.ShouldDrawMarkerOnViewEdgeX())
			{
				if ((logValue == this.HAxis.ViewMaximum) && (this.ShiftedX >= 0.0))
				{
					return;
				}
				if ((logValue == this.HAxis.ViewMinimum) && (this.ShiftedX <= 0.0))
				{
					return;
				}
			}
			PointF empty = PointF.Empty;
			empty.Y = (float)pointEx.yPosition;
			empty.X = (float)this.HAxis.GetLinearPosition(logValue);
			empty.X += (float)this.ShiftedX;
			dataPoint.positionRel = new PointF(empty.X, empty.Y);
			int markerSize = dataPoint.MarkerSize;
			string markerImage = dataPoint.MarkerImage;
			MarkerStyle markerStyle = dataPoint.MarkerStyle;
			SizeF size = this.GetMarkerSize(graph, common, area, dataPoint, markerSize, markerImage);
			Point3D[] points = new Point3D[] { new Point3D(empty.X, empty.Y, pointEx.zPosition + (this.middleMarker ? (pointEx.depth / 2f) : pointEx.depth)) };
			area.matrix3D.TransformPoints(points);
			PointF pointF = points[0].PointF;
			GraphicsPath path = null;
			if (((this.alwaysDrawMarkers || (markerStyle != MarkerStyle.None)) || (markerImage.Length > 0)) && ((pointEx.index % series.MarkerStep) == 0))
			{
				DrawingOperationTypes drawElement = DrawingOperationTypes.DrawElement;
				if (common.ProcessModeRegions)
				{
					drawElement |= DrawingOperationTypes.CalcElementPath;
				}
				graph.StartHotRegion(dataPoint);
				path = graph.DrawMarker3D(area.matrix3D, area.Area3DStyle.LightStyle, pointEx.zPosition + (this.middleMarker ? (pointEx.depth / 2f) : pointEx.depth), empty, (markerStyle == MarkerStyle.None) ? MarkerStyle.Circle : markerStyle, (int)size.Height, (dataPoint.MarkerColor == Color.Empty) ? dataPoint.Color : dataPoint.MarkerColor, (dataPoint.MarkerBorderColor == Color.Empty) ? dataPoint.BorderColor : dataPoint.MarkerBorderColor, this.GetMarkerBorderSize(dataPoint), markerImage, dataPoint.MarkerImageTransparentColor, (dataPoint.series != null) ? dataPoint.series.ShadowOffset : 0, (dataPoint.series != null) ? dataPoint.series.ShadowColor : Color.Empty, new RectangleF(pointF.X, pointF.Y, size.Width, size.Height), drawElement);
				graph.EndHotRegion();
			}
			if (((this.label3DInfoList != null) && (this.label3DInfoList.Count > 0)) && (((Label3DInfo)this.label3DInfoList[this.label3DInfoList.Count - 1]).PointEx.zPosition != pointEx.zPosition))
			{
				this.DrawAccumulated3DLabels(graph, common, area);
			}
			if (this.label3DInfoList == null)
			{
				this.label3DInfoList = new ArrayList();
			}
			Label3DInfo info = new Label3DInfo();
			info.PointEx = pointEx;
			info.MarkerPosition = pointF;
			info.MarkerSize = size;
			this.label3DInfoList.Add(info);
			if (common.ProcessModeRegions)
			{
				SizeF relativeSize = graph.GetRelativeSize(size);
				int insertIndex = common.HotRegionsList.FindInsertIndex();
				switch (markerStyle)
				{
					case MarkerStyle.Circle:
						{
							float[] numArray = new float[] { pointF.X, pointF.Y, relativeSize.Width / 2f };
							common.HotRegionsList.AddHotRegion(insertIndex, graph, numArray[0], numArray[1], numArray[2], dataPoint, series.Name, pointEx.index - 1);
							break;
						}
					case MarkerStyle.Square:
						common.HotRegionsList.AddHotRegion(path, false, graph, dataPoint, series.Name, pointEx.index - 1);
						goto Label_04D1;
				}
				common.HotRegionsList.AddHotRegion(new RectangleF(pointF.X - (relativeSize.Width / 2f), pointF.Y - (relativeSize.Height / 2f), relativeSize.Width, relativeSize.Height), dataPoint, series.Name, pointEx.index - 1);
			}
		Label_04D1:
			if (path != null)
			{
				path.Dispose();
			}
		}

		private void SetHotRegions(CommonElements common, ChartGraphics graph, DataPoint point, SizeF markerSize, string seriesName, int pointIndex, MarkerStyle pointMarkerStyle, PointF markerPosition)
		{
			SizeF relativeSize = graph.GetRelativeSize(markerSize);
			int insertIndex = common.HotRegionsList.FindInsertIndex();
			if (pointMarkerStyle == MarkerStyle.Circle)
			{
				common.HotRegionsList.AddHotRegion(insertIndex, graph, markerPosition.X, markerPosition.Y, relativeSize.Width / 2f, point, seriesName, pointIndex);
			}
			else
			{
				common.HotRegionsList.AddHotRegion(new RectangleF(markerPosition.X - (relativeSize.Width / 2f), markerPosition.Y - (relativeSize.Height / 2f), relativeSize.Width, relativeSize.Height), point, seriesName, pointIndex);
			}
		}

		protected virtual bool ShouldDrawMarkerOnViewEdgeX()
		{
			return true;
		}

		public virtual bool ApplyPaletteColorsToPoints
		{
			get
			{
				return false;
			}
		}

		internal ChartArea Area { set; get; }

		public bool CircularChartArea
		{
			get
			{
				return false;
			}
		}

		internal CommonElements Common { set; get; }

		public virtual bool DataPointsInLegend
		{
			get
			{
				return false;
			}
		}

		public virtual bool ExtraYValuesConnectedToYAxis
		{
			get
			{
				return false;
			}
		}

		internal Axis HAxis { get; set; }

		public virtual bool HundredPercent
		{
			get
			{
				return false;
			}
		}

		public virtual bool HundredPercentSupportNegative
		{
			get
			{
				return false;
			}
		}

		public virtual string Name
		{
			get
			{
				return "Point";
			}
		}

		public virtual bool RequireAxes
		{
			get
			{
				return true;
			}
		}

		public virtual bool SecondYScale
		{
			get
			{
				return false;
			}
		}

		public virtual string ShiftedSerName
		{
			get
			{
				return "";
			}
			set
			{
			}
		}

		public virtual double ShiftedX
		{
			get
			{
				return 0.0;
			}
			set
			{
			}
		}

		public virtual bool SideBySideSeries
		{
			get
			{
				return false;
			}
		}

		public virtual bool Stacked
		{
			get
			{
				return false;
			}
		}

		public bool StackSign
		{
			get
			{
				return false;
			}
		}

		public virtual bool SupportLogarithmicAxes
		{
			get
			{
				return true;
			}
		}

		public virtual bool SupportStackedGroups
		{
			get
			{
				return false;
			}
		}

		public virtual bool SwitchValueAxes
		{
			get
			{
				return false;
			}
		}

		internal Axis VAxis { set; get; }

		internal int YValueIndex { set; get; }

		public virtual int YValuesPerPoint
		{
			get
			{
				return 1;
			}
		}

		public virtual bool ZeroCrossing
		{
			get
			{
				return false;
			}
		}

		internal class Label3DInfo
		{
			internal PointF MarkerPosition = PointF.Empty;
			internal SizeF MarkerSize = SizeF.Empty;
			internal DataPoint3D PointEx;
		}
	}
}

